#include "string_utils.h"

#include <sstream>
#include <algorithm>
#include <functional>
#include <cctype>

using std::string;
using std::vector;

void split(const string& str, char delimiter, vector<string>* tokens, bool skipEmpty /*= true */) {
    tokens->clear();
    std::stringstream ss(str);
    std::string item;
    while (std::getline(ss, item, delimiter)) {
        if (!skipEmpty || !item.empty()) {
            tokens->push_back(item);
        }
    }
}

void joinStrings(const vector<string>& tokens, const char* separator, string* joined) {
    joined->clear();
    std::ostringstream out(*joined);
    for (size_t i = 0; i < tokens.size(); ++i) {
        if (i != 0) {
            out << separator;
        }
        out << tokens[i];
    }
}

struct IsPunctuation {
    bool operator()(char c) const {
        return c == '.' || c == ',' || c == '\'' || c == '?' || c == '!' || c == ';' || c == '-';
    }
};

void killPunctuation(std::string& str) {
    std::replace_if(str.begin(), str.end(), IsPunctuation(), ' ');
}

// trim from start
void ltrim(std::string& s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(::isspace))));
}

// trim from end
void rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(::isspace))).base(), s.end());
}

// trim from both ends
void trim(std::string& s) {
    rtrim(s);
    ltrim(s);
}
